package com.ueboot.weishop.service.order.impl;

import com.google.common.collect.Lists;
import com.ueboot.weishop.entity.order.OrderEnum;
import com.ueboot.weishop.entity.order.OrderInvoiceEntity;
import com.ueboot.weishop.repository.order.OrderInvoiceNewRepository;
import com.ueboot.weishop.service.order.OrderInvoiceNewService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OrderInvoiceNewServiceImpl implements OrderInvoiceNewService {

    @Autowired
    private OrderInvoiceNewRepository orderInvoiceNewRepository;

    @Override
    public List<OrderInvoiceEntity> findSearch(OrderInvoiceEntity model, String orderNo, Date invoiceCreateStart, Date invoiceCreateEnd) {
        Assert.notNull(model);
        List<OrderInvoiceEntity> orderEntityList = orderInvoiceNewRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicateList = this.commonPredicates(root, criteriaBuilder, model, orderNo, invoiceCreateStart, invoiceCreateEnd);
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates));
        });
        return orderEntityList;
    }

    @Override
    public Page<OrderInvoiceEntity> pagingSearch(Pageable pageable, OrderInvoiceEntity model, String orderNo, Date invoiceCreateStart, Date invoiceCreateEnd) {
        Assert.notNull(model);
        Page<OrderInvoiceEntity> pageDataOrder = orderInvoiceNewRepository.findAll((root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = this.commonPredicates(root, criteriaBuilder, model, orderNo, invoiceCreateStart, invoiceCreateEnd);
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates));
        }, pageable);
        return pageDataOrder;
    }

    private List<Predicate> commonPredicates(Root<OrderInvoiceEntity> root, CriteriaBuilder criteriaBuilder, OrderInvoiceEntity model, String orderNo, Date invoiceCreateStart, Date invoiceCreateEnd) {
        List<Predicate> predicateList = Lists.newLinkedList();

        if (StringUtils.isNotEmpty(model.getInvoiceType())) {
            predicateList.add(criteriaBuilder.equal(root.get("invoiceType").as(String.class), model.getInvoiceType()));
        }

        if (StringUtils.isNotEmpty(orderNo)) {
            predicateList.add(criteriaBuilder.equal(root.get("order").get("orderNo").as(String.class), orderNo));
        }
        predicateList.add(criteriaBuilder.equal(root.get("order").get("orderStatus").as(String.class), OrderEnum.ORDER_STATUS_2));
        predicateList.add(criteriaBuilder.equal(root.get("order").get("needInvoice").as(Boolean.class), Boolean.TRUE));
        if (invoiceCreateStart != null) {
            predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("firstInsert").as(Date.class), invoiceCreateStart));
        }

        if (invoiceCreateEnd != null) {
            predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("firstInsert").as(Date.class), invoiceCreateEnd));
        }
        return predicateList;
    }
}
